/******************************************************************************
 * Copyright (C) 2013 - 2018 ShenZhen OnePlus Technology Co.,Ltd All Rights Reserved.
 * 本软件为深圳万普拉斯科技有限公司开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、复制、修改或发布本软件.
 *****************************************************************************/
package com.data.reports.support;

import com.data.reports.export.excel.ExcelExportUtil;
import com.data.reports.export.excel.ViewExcelUtil;
import com.data.reports.manager.ConfigInvocationHandlerFactory;
import com.data.reports.manager.SqlConfigService;
import com.data.reports.manager.SqlReportConfig;
import com.data.reports.manager.database.DataSourceConfigService;
import com.data.reports.utils.JSONUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Hurricane.Hu
 * @version V1.0
 * @Title: SqlReportServlet.java
 * @Package com.data.com.data.reports.support
 * @Description
 * @date 2018 03-12 16:29.
 */
public class SqlReportServlet extends ResourceServlet {

    private static final long serialVersionUID = -4864485546538721360L;

    private SqlConfigService sqlConfigService;

    private DataSourceConfigService dataSourceConfigService;

    public void setSqlConfigService(SqlConfigService sqlConfigService) {
        this.sqlConfigService = sqlConfigService;
    }

    public void setDataSourceConfigService(DataSourceConfigService dataSourceConfigService) {
        this.dataSourceConfigService = dataSourceConfigService;
    }

    public SqlReportServlet() {
        super("http/resources");
    }

    public static String returnJSONResult(int resultCode, Object content) {
        Map<String, Object> dataMap = new LinkedHashMap<>();
        dataMap.put("ResultCode", resultCode);
        dataMap.put("Content", content);
        return JSONUtils.toJsonStr(dataMap);
    }

    public static Map<String, String> getParameters(String url) {
        if (url != null && (url = url.trim()).length() != 0) {
            String parametersStr = StringUtils.substring(url, url.indexOf("?") + 1);
            if (parametersStr.length() != 0) {
                String[] parametersArray = parametersStr.split("&");
                Map<String, String> parameters = new LinkedHashMap<>();
                String[] var4 = parametersArray;
                int var5 = parametersArray.length;

                for (int var6 = 0; var6 < var5; ++var6) {
                    String parameterStr = var4[var6];
                    int index = parameterStr.indexOf("=");
                    if (index > 0) {
                        String name = parameterStr.substring(0, index);
                        String value = parameterStr.substring(index + 1);
                        parameters.put(name, value);
                    }
                }

                return parameters;
            } else {
                return Collections.emptyMap();
            }
        } else {
            return Collections.emptyMap();
        }
    }

    @Override
    protected String process(String url, HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> parameters = getParameters(url);
        if (url.startsWith("/index.json")) {
            return returnJSONResult(1, sqlConfigService.listSqlReportConfigPage(parameters));
        } else if (url.startsWith("/report-detail")) {
            String id = StringUtils.substringBetween(url, "report-detail-", ".json");
            if (StringUtils.isNotBlank(id) && NumberUtils.isNumber(id)) {
                return returnJSONResult(1, sqlConfigService.getSqlReportConfigById(Integer.parseInt(id)));
            }
        } else if (url.startsWith("/report-download")) {
            String id = parameters.get("reportId");
            if (StringUtils.isNotBlank(id) && NumberUtils.isNumber(id)) {
                SqlReportConfig sqlReportConfig = sqlConfigService.getSqlReportConfigById(Integer.parseInt(id));
                if (sqlReportConfig != null && StringUtils.isNotBlank(sqlReportConfig.getSqlContent())) {
                    SqlRowSet sqlRowSet = sqlConfigService.getResultSet4ExecuteReportSql(sqlReportConfig,null);
                    String fileName = sqlReportConfig.getReportName()
                                      + new SimpleDateFormat("yyyy-MM-dd").format(new Date())
                                      + ".xlsx";
                    try {
                        ViewExcelUtil.buildExcelDocument(fileName,
                                                         ExcelExportUtil.resultSetToExcel(sqlRowSet, "", 50000),
                                                         response);
                    }
                    catch (Exception e) {
                        returnJSONResult(-1, "Export data error.");
                    }
                }
                return returnJSONResult(-1, "Sql is required.");
            }
        } else if (url.startsWith("/report-save")) {
            String id = request.getParameter("id");
            String dbCode = request.getParameter("dbCode");
            String configCode = request.getParameter("configCode");
            String reportName = request.getParameter("reportName");
            String reportDesc = request.getParameter("reportDesc");
            String sqlContent = request.getParameter("sqlContent");

            if (StringUtils.isNotBlank(id) && NumberUtils.isNumber(id)) {
                SqlReportConfig sqlReportConfig = new SqlReportConfig();
                sqlReportConfig.setId(Integer.parseInt(id));
                sqlReportConfig.setDbCode(dbCode);
                sqlReportConfig.setConfigCode(configCode);
                sqlReportConfig.setReportName(reportName);
                sqlReportConfig.setReportDesc(reportDesc);
                sqlReportConfig.setSqlContent(sqlContent);
                try {
                    sqlConfigService.updateSqlReportConfig(sqlReportConfig);
                    return returnJSONResult(1, Integer.parseInt(id));
                } catch (Exception e) {
                    return returnJSONResult(-1, e.getMessage());
                }
            } else {
                SqlReportConfig sqlReportConfig = new SqlReportConfig();
                sqlReportConfig.setDbCode(dbCode);
                sqlReportConfig.setConfigCode(configCode);
                sqlReportConfig.setReportName(reportName);
                sqlReportConfig.setReportDesc(reportDesc);
                sqlReportConfig.setSqlContent(sqlContent);
                try {
                    Integer configId = sqlConfigService.addSqlReportConfig(sqlReportConfig);
                    return returnJSONResult(1,configId);
                } catch (Exception e) {
                    return returnJSONResult(-1, e.getMessage());
                }

            }
        } else if (url.startsWith("/report-delete")) {
            String id = parameters.get("reportId");
            if (StringUtils.isNotBlank(id) && NumberUtils.isNumber(id)) {
                return returnJSONResult(1, sqlConfigService.deleteSqlReportConfig(Integer.parseInt(id)));
            }
        } else if (url.startsWith("/datasource.json")) {
            return returnJSONResult(1, dataSourceConfigService.listDataSourcePage(parameters));
        }
        return null;
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        ServletContext servletContext = config.getServletContext();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        SqlConfigService sqlConfigService=webApplicationContext.getBean(SqlConfigService.class);
        DataSourceConfigService dataSourceConfigService=webApplicationContext.getBean(DataSourceConfigService.class);
        //使用jdk代理拦截，拦截没有切换数据源注解表示的接口使用默认的数据源

        setSqlConfigService(ConfigInvocationHandlerFactory.getProxy(sqlConfigService));
        setDataSourceConfigService(ConfigInvocationHandlerFactory.getProxy(dataSourceConfigService));
    }
}
